package com.tidc.manage.exception;

import com.tidc.manage.tool.RestfulVOResultBuilder;
import com.tidc.manage.vo.RestfulVO;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.xml.ws.Response;
import java.util.ArrayList;
import java.util.List;

/**
 * Description:
 * 全局异常处理器
 * <code>ControllerAdvice的类注解</code>用于捕捉全局异常，进行统一异常处理
 *
 * @author 张朝锋
 * @date 2018-09-20
 */
@ControllerAdvice
public class GlobalExceptionHandler implements RestfulVOResultBuilder {

    /**
     * 处理，实际为捕捉全局异常
     *
     * @param exception 全局异常
     * @return 具体异常信息
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<RestfulVO> handlerException(Exception exception) {
        //当未知异常发生时，将信息弹出堆栈
        exception.printStackTrace();
        return new ResponseEntity<>(
                failedMessage(1000, exception.getMessage()),
                HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * 处理 Spring boot 注解校验异常 并改为 自定义异常信息
     *
     * @param methodArgumentNotValidException Spring boot 注解校验异常
     * @return 自定具体异常处理结果
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<RestfulVO> handlerMethodArgumentNotValidException(MethodArgumentNotValidException methodArgumentNotValidException) {
        List<ObjectError> errorList = methodArgumentNotValidException.getBindingResult().getAllErrors();
        String message;
        if (errorList.size() != 1) {
            List<String> errorsMessage = new ArrayList<>();
            errorList.forEach(error -> errorsMessage.add(error.getDefaultMessage()));
            String defaultDelimiter = " AND ";
            message = "Multiple errors: " + String.join(defaultDelimiter, errorsMessage);
        } else {
            message = errorList.get(0).getDefaultMessage();
        }
        return new ResponseEntity<>(
                failedMessage(1111, message),
                HttpStatus.BAD_REQUEST);
    }

    /**
     * 处理 数据为零的异常
     *
     * @param zeroException 零异常
     * @return 具体异常信息
     */
    @ExceptionHandler(ZeroException.class)
    public ResponseEntity<RestfulVO> handlerZeroException(ZeroException zeroException) {
        return new ResponseEntity<>(failedMessage(1001,
                "The " + zeroException.getValueName() + " can't be zero."),
                HttpStatus.BAD_REQUEST);
    }

    /**
     * 处理 http消息不可读异常
     *
     * @param httpMessageNotReadableException http消息不可读异常
     * @return 具体异常信息
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity<RestfulVO> handlerHttpMessageNotReadableException(HttpMessageNotReadableException httpMessageNotReadableException) {
        return new ResponseEntity<>(failedMessage(1003,
                httpMessageNotReadableException.getMessage()),
                HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * 处理 找不到异常
     *
     * @param notFoundException notFoundException
     * @return 具体异常信息
     */
    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<RestfulVO> handlerNotFoundException(NotFoundException notFoundException) {
        return new ResponseEntity<>(failedMessage(1004,
                notFoundException.getMessage() + " is not found."),
                HttpStatus.NOT_FOUND);
    }

    /**
     * 处理 数据匹配失败
     *
     * @param mismatchException 匹配失败异常
     * @return 具体异常信息
     */
    @ExceptionHandler(MismatchException.class)
    public ResponseEntity<RestfulVO> handlerMismatchException(MismatchException mismatchException) {
        return new ResponseEntity<>(failedMessage(1002,
                mismatchException.getMessage()),
                HttpStatus.BAD_REQUEST);
    }

    /**
     * 处理 用户登录异常
     *
     * @param authenticationFailureException 认证失败异常
     * @return 具体异常信息
     */
    @ExceptionHandler(AuthenticationFailureException.class)
    public ResponseEntity<RestfulVO> handlerAuthenticationFailureException(AuthenticationFailureException authenticationFailureException) {
        authenticationFailureException.printStackTrace();
        return new ResponseEntity<>(failedMessage(1006,
                authenticationFailureException.getMessage()),
                HttpStatus.UNAUTHORIZED);
    }

    /**
     * 处理 空指针异常
     * @param nullPointerException 空指针异常
     * @return 具体异常信息
     */
    @ExceptionHandler(NullPointerException.class)
    public ResponseEntity<RestfulVO> handlerNullPointerException(NullPointerException nullPointerException){
        nullPointerException.getMessage();
        return new ResponseEntity<>(failedMessage(1013,
                nullPointerException.getMessage()),
                HttpStatus.BAD_REQUEST);
    }
}